﻿using System;

namespace Songhay
{
    public static partial class FrameworkType
    {
        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"></see> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"></see> box.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"></see>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static bool? ParseBoolean(object frameworkValue)
        {
            bool supportBitStrings = false;
            return ParseBoolean(frameworkValue, supportBitStrings);
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <param name="supportBitStrings">
        /// When <c>true</c>, support "1" and "0"
        /// as Boolean strings.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static bool? ParseBoolean(object frameworkValue, bool supportBitStrings)
        {
            bool bln;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;

            if(supportBitStrings)
            {
                if(s.Trim().Equals("0")) return new bool?(false);
                if(s.Trim().Equals("1")) return new bool?(true);
            }

            if(bool.TryParse(s, out bln)) return bln;
            else return new bool?();
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static byte? ParseByte(object frameworkValue)
        {
            byte b;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;
            if(byte.TryParse(s, out b)) return b;
            else return new byte?();
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static DateTime? ParseDateTime(object frameworkValue)
        {
            DateTime d;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;
            if(DateTime.TryParse(s, out d)) return d;
            else return new DateTime?();
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <param name="formatExpression">
        /// The string format expression.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static string ParseDateTimeWithFormat(object frameworkValue, string formatExpression)
        {
            DateTime d;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;
            if(DateTime.TryParse(s, out d)) return d.ToString(formatExpression);
            else return null;
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static double? ParseDouble(object frameworkValue)
        {
            double d;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;
            if(double.TryParse(s, out d)) return d;
            else return new double?();
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to the <see cref="System.Nullable"/> return type.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        /// <returns>
        /// Always returns a <see cref="System.Nullable"/>
        /// as parse failure means <c>HasValue</c>
        /// is false.
        /// </returns>
        public static Int32? ParseInt32(object frameworkValue)
        {
            Int32 i;
            string s = (frameworkValue != null) ? frameworkValue.ToString() : string.Empty;
            if(Int32.TryParse(s, out i)) return i;
            else return new Int32?();
        }

        /// <summary>
        /// Tries to convert the specified value
        /// to a <see cref="System.string"/>.
        /// </summary>
        /// <param name="frameworkValue">
        /// The specified <see cref="System.object"/> box.
        /// </param>
        public static string ParseString(object frameworkValue)
        {
            return (frameworkValue != null) ? frameworkValue.ToString() : null;
        }
    }
}
